
#include "threadpool.h"
#include <unistd.h>

//********************************************************************************
//初始化线程池
//********************************************************************************
void threadpoolInit(thread_pool_t* pthreadpool, int threadNum)
{
    pthreadpool->threadNumber = threadNum;
    pthreadpool->threads = (pthread_t*)calloc(threadNum, sizeof(pthread_t));
    queueInit(&pthreadpool->queue);
}

//********************************************************************************
//销毁线程池
//********************************************************************************
void threadpoolDestroy(thread_pool_t* pthreadpool)
{
    free(pthreadpool->threads);
    queueDestroy(&pthreadpool->queue);
}

//********************************************************************************
//创建子线程，开启线程池
//********************************************************************************
void threadpoolStart(thread_pool_t * pthreadpool)
{
    for(int idx = 0; idx < pthreadpool->threadNumber; ++idx) {
        int ret = pthread_create(&pthreadpool->threads[idx],
                                 NULL, 
                                 threadFunc, 
                                 pthreadpool);
        THREAD_ERROR_CHECK(ret, "pthread_create");
    }
}

//********************************************************************************
//线程处理函数
//********************************************************************************
void * threadFunc(void* arg)
{
    //每一个子线程要做的事儿
    printf("sub thread %ld is runing\n", pthread_self());
    thread_pool_t * pthreadpool = (thread_pool_t*)arg;
    while(1)
    {
        task_t * pNode = taskDequeue(&pthreadpool->queue);
        printf("开始发送\n");
        printf("peerfd = %d,data = %s\n",pNode->peerfd,pNode->data);

        // //***********************可以在这里测试********************
        // //pNode->type表示指令类型,pNode->data表示参数。
        // //返回小火车结构体
        // 		train_t sendmsgs;
        // 		sendmsgs.len = 100;
        // 		strcpy(sendmsgs.data,pNode->data);
        // 		send(pNode->peerfd,&sendmsgs,sendmsgs.len + 4,MSG_WAITALL);
        // //********************************************************

        printf("before mkdir\n");
        mkDir(pNode->peerfd,pNode->data);
        
        printf("发送完毕\n");
        free(pNode);

        //printf("before Send\n");
        //Sendls(pNode->peerfd, pNode->data);
        //printf("发送完毕\n");
        //free(pNode);
    }
    // while(1) {
    // task_t * pNode = taskDequeue(&pthreadpool->queue);
    // //定义函数指针变量
    // handleCmd handle;
    // if(pNode != NULL) {
    // 	//执行任务
    // 	switch(pNode->type)
    // 	{
    // 		case CMD_TYPE_CD:
    // 			handle(pNode->peerfd,pNode->data);
    // 			break;
    // 		case CMD_TYPE_LS:
    // 			handle(pNode->peerfd,pNode->data);
    // 			break;
    // 		case CMD_TYPE_PWD:
    // 			handle(pNode->peerfd,pNode->data);
    // 			break;
    // 		case CMD_TYPE_PUT:
    // 			handle(pNode->peerfd,pNode->data);
    // 			break;
    // 		case CMD_TYPE_GET:
    // 			handle(pNode->peerfd,pNode->data);
    // 			break;
    // 		case CMD_TYPE_RM:
    // 			handle(pNode->peerfd,pNode->data);
    // 			break;
    // 		case CMD_TYPE_MKDIR:
    // 			handle(pNode->peerfd,pNode->data);
    // 			break;
    // 		default:
    // 			break;
    // 	}
    // } else {
    // 	break;
    // }
    //执行完毕释放结点
    // 	free(pNode);
    // }
    printf("sub thread %ld is ready to exit\n", pthread_self());
    pthread_exit(0);
}

void mkDir(int peerfd, char *pathname){
    if(strcmp(pathname, " ") == 0){
        char msg[BUFFSIZE] = "路径名为空，请重新输入。";
        int length = strlen(msg);
        train_t train;
        memset(&train, 0, sizeof(train));
        train.len = length;
        strcpy(train.data, msg);
        send(peerfd, &train, 4 + train.len, MSG_WAITALL);
        return;
    }
    int retval = mkdir(pathname, 0777);
    if(retval == -1){
        char errmsg[BUFFSIZE] = {0};
        sprintf(errmsg, "%s", strerror(errno));
        train_t train;
        train.len = strlen(errmsg);
        strcpy(train.data, errmsg);
        send(peerfd, &train, 4 + train.len, MSG_WAITALL);
        return;
    }
    char sucessmsg[BUFFSIZE] = "mkdir sucess.";
    train_t train;
    train.len = strlen(sucessmsg);
    strcpy(train.data, sucessmsg);
    send(peerfd, &train, 4 + train.len, MSG_WAITALL);
    return;
}                        
int Sendls(int peerfd, char *pathname){                                                                                            
    if(strlen(pathname) == 0){
        strcpy(pathname, "./");
    }
    DIR *pdir = opendir(pathname);
    if(pdir == NULL){
        char errmsg[BUFFSIZE] = {0};
        sprintf(errmsg, "%s\n", strerror(errno));
        train_t train;
        train.len = strlen(errmsg);
        strcpy(train.data, errmsg);
        send(peerfd, &train, 4 + train.len, MSG_WAITALL);
        printf("err:%s", train.data);
        return -1;
    }
    //ERROR_CHECK(pdir, NULL, "opendir");
    struct stat statbuf;
    struct dirent *pdirent;
    errno = 0;
    char sendbuf[1024] = {0};
    while((pdirent = readdir(pdir)) != NULL){
        if(pdirent->d_name[0] == '.'){
            continue;
        }
        if(pdirent->d_type == DT_DIR){
            char path[1024];
            sprintf(path, "%s/%s", pathname, pdirent->d_name);
            int retval = stat(path, &statbuf);
            //ERROR_CHECK(retval, -1, "stat");
            struct tm* ptime = localtime(&statbuf.st_atime);
            //ERROR_CHECK(ptime, NULL, "localtime");
            char dmsg[1024] = {0};
            sprintf(dmsg, BLUE "%s/ %ld %d/%.2d/%.2d %.2d:%.2d:%.2d \n",
                    pdirent->d_name, statbuf.st_size,
                    ptime->tm_year + 1900,
                    ptime->tm_mon + 1,
                    ptime->tm_mday,
                    ptime->tm_hour,
                    ptime->tm_min,
                    ptime->tm_sec);
            strcat(sendbuf, dmsg);
            //send(peerfd, sendbuf, strlen(sendbuf), MSG_WAITALL);
        }
    }
    closedir(pdir);
    pdir = opendir(pathname);
    while((pdirent = readdir(pdir)) != NULL){
        if(pdirent->d_name[0] == '.'){
            continue;
        }
        if(pdirent->d_type == DT_REG){
            char path[1024];
            sprintf(path, "%s/%s", pathname, pdirent->d_name);
            int retval = stat(path, &statbuf);
            ERROR_CHECK(retval, -1, "stat");
            struct tm* ptime = localtime(&statbuf.st_atime);
            ERROR_CHECK(ptime, NULL, "localtime");
            char rmsg[1024] = {0};
            sprintf(rmsg, NONE "%s %ld %d/%.2d/%.2d %.2d:%.2d:%.2d \n",
                    pdirent->d_name, statbuf.st_size,
                    ptime->tm_year + 1900,
                    ptime->tm_mon + 1,
                    ptime->tm_mday,
                    ptime->tm_hour,
                    ptime->tm_min,
                    ptime->tm_sec);
            strcat(sendbuf, rmsg);
            //send(peerfd, sendbuf, strlen(sendbuf), MSG_WAITALL);
        }
    }
    train_t train;
    train.len = strlen(sendbuf);
    strcpy(train.data, sendbuf);
    send(peerfd, &train, 4 + train.len, MSG_WAITALL);
    closedir(pdir);
    printf("end:%s", train.data);
    return 0;
}


//void cd(int peerfd, char* buf) {
//
//	printf("buf = %s\n",buf);
//
//    int retval = chdir(buf);
//	if(retval == -1)
//	{
//		send();
//		return;
//	}
//	printf("after chdir\n");
//
//    char *pathname = getwd(buf);
//
//	printf("pathname = %s\n",pathname);
//
//    train_t sendmsgs;
//	sendmsgs.len = strlen(pathname) + 1;  //先传返回信息的大小
//	strcpy(sendmsgs.data, pathname);  //再传返回的信息
//
//	printf("sendmsgs.data = %s\n",sendmsgs.data);
//    send(peerfd, &sendmsgs, sendmsgs.len + 4, MSG_WAITALL);
//	printf("sendmsgs.len = %d\n",sendmsgs.len);
//	printf("after send\n");
//}

